package org.water.common.interceptors;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.water.base.entity.LogBean;
import org.water.common.bind.annotation.MethodDesc;
import org.water.common.log.BaseLog;
import org.water.common.param.ConstParams;
import org.water.common.util.RequestUtil;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.hutool.log.Log;


/**
 * 公共拦截器，设置公共的信息
 * @author qzy
 *
 */
public class CommonInterceptor extends HandlerInterceptorAdapter {
	
	private static Logger userLogger=LogManager.getLogger("user.oprate.log");
	private static Logger log=LogManager.getLogger(CommonInterceptor.class);
	 /**
	  * 上下文路径变量名,用于jsp页面中jstl直接获取，方式${ctx}
	  */
	 private String ctx = "ctx";
	/**
	 * 处理前
	 * 设置公共的参数
	 * ctx
	 * app_name
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
	        throws Exception
    {
		request.setAttribute(ctx, request.getContextPath());
		//methodHadler(request,response,handler,"start");
		//log.debug(request.getSession());
		log.debug(request.getRequestURI());
		startLogBean(request);
        return true;
    }
	/**
	 * 处理中
	 */
	@Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelandview)
        throws Exception
    {
		LogBean logBean=BaseLog.getLogBean(Thread.currentThread().getId());
		if(logBean!=null && modelandview!=null)
		{
			logBean.setPage(1);
			//logBean.setPageView(modelandview.toString());
		}
    }
	/**
	 * 处理后
	 */
	@Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception)
        throws Exception
    {
		//methodHadler(request,response,handler,"end");
		if(handler instanceof HandlerMethod)
		{
			userOprateHandler(request, handler);//用户操作记录
		}
		LogBean logBean=BaseLog.getLogBean(Thread.currentThread().getId());
		if(logBean!=null)
		{
			logBean.setResponseStatus(response.getStatus());
			logBean.setResponseContentType(response.getContentType());
			logBean.setEndTime(System.currentTimeMillis());
			BaseLog.recordLog(logBean);
		}
    }

	/**
	 * 处理开始之后 
	 */
    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse, Object handler)
        throws Exception
    {
    }
	public String getCtx() {
		return ctx;
	}
	public void setCtx(String ctx) {
		this.ctx = ctx;
	}
    /**
     * 方法handler处理器
     * @param handler
     */
	protected void methodHadler(HttpServletRequest request, HttpServletResponse response, Object handler,String type)
	{
		if(handler instanceof HandlerMethod)//方法处理
		{
			BaseLog.recordLog(request, type); //记录访问方法的日志
		}
		else if(handler instanceof ResourceHttpRequestHandler) //静态资源处理
		{
			
		}
	}
	/**
	 * 用户操作记录,针对方法加了MethodDesc注解的日志记录
	 * @param request
	 * @param handler
	 */
	protected void userOprateHandler(HttpServletRequest request,Object handler)
	{
		HandlerMethod handlerMethod=(HandlerMethod) handler;
		if(handlerMethod.getMethodAnnotation(MethodDesc.class)!=null)
		{
			LogBean logBean=BaseLog.getLogBean(Thread.currentThread().getId());
			MethodDesc md=handlerMethod.getMethodAnnotation(MethodDesc.class);
			Subject subject=null;
			if(request instanceof ShiroHttpServletRequest)
			{
			    subject=SecurityUtils.getSubject();
			}
			if(subject!=null && subject.getSession().getAttribute(ConstParams.CURRENT_USERNAME)!=null && logBean!=null && md!=null)
			{
				logBean.setModuleName(md.name());
				logBean.setOprateDesc(md.value());
				
				userLogger.info(JSON.toJSONString(logBean));
			}
		}
		
	}
	/**
	 * 开始记录公共日志
	 */
	protected void startLogBean(HttpServletRequest request)
	{
		LogBean logBean=new LogBean();
		logBean.setUrl(request.getRequestURI());
		logBean.setStartTime(System.currentTimeMillis());
		logBean.setExecThreadId(Thread.currentThread().getId());
		logBean.setParams(RequestUtil.getParamStr(request));
		logBean.setIp(request.getRemoteAddr());
		//logBean.setRequestHeader(getRequestHeader(request).toJSONString());
		logBean.setUserAgent(request.getHeader("user-agent"));
		logBean.setHostName(request.getRemoteHost());
		Subject subject=null;
		if(request instanceof ShiroHttpServletRequest)
		{
		    subject=SecurityUtils.getSubject();
		}
		if(subject!=null && subject.getSession().getAttribute(ConstParams.CURRENT_USERNAME)!=null)
		{
			logBean.setUserName(subject.getSession().getAttribute(ConstParams.CURRENT_USERNAME).toString());
		}
		else
		{
			logBean.setUserName(BaseLog.EMPTY_USER);
		}
		BaseLog.addLogBean(logBean);
	}
	/**
	 * 获取请求头
	 * @param request
	 * @return
	 */
	protected JSONObject getRequestHeader(HttpServletRequest request)
	{
		JSONObject json=new JSONObject();
		Enumeration<String> headerNames=request.getHeaderNames();
		while(headerNames.hasMoreElements())
		{
			String headerName=headerNames.nextElement();
			json.put(headerName, request.getHeader(headerName));
		}
		return json;
	}
}
